/*
 * File:   ColaPriorizacionTest.c
 * Author: Maximiliano Monzon
 *
 * Created on Sep 16, 2012, 1:54:39 AM
 */

#include <stdio.h>
#include <stdlib.h>

#include "../Trabajo.h"
#include "../ColaPriorizacion.h"
#include "TDA_Lista.h"

static void imprimirTrabajo (tTrabajo pTrabajo);
void imprimirTrabajos (tLista pTrabajos);
void imprimirColaPriorizacion (tColaPriorizacion pColaPriorizacion);

void test1();
void test2();
void test3();
void test4();

/*
 * Simple C Test Suite
 */



int main(int argc, char** argv) {
    /*
    printf("%%SUITE_STARTING%% ColaPriorizacionTest\n");
    printf("%%SUITE_STARTED%%\n");

    printf("%%TEST_STARTED%% test1 (ColaPriorizacionTest)\n");
    test1();
    printf("%%TEST_FINISHED%% time=0 test1 (ColaPriorizacionTest) \n");
*/
    printf("%%TEST_STARTED%% test2 (ColaPriorizacionTest)\n");
    test2();
    printf("%%TEST_FINISHED%% time=0 test2 (ColaPriorizacionTest) \n");
/*
    printf("%%TEST_STARTED%% test3 (ColaPriorizacionTest)\n");
    test3();
    printf("%%TEST_FINISHED%% time=0 test3 (ColaPriorizacionTest) \n");

    printf("%%TEST_STARTED%% test4 (ColaPriorizacionTest)\n");
    test4();
    printf("%%TEST_FINISHED%% time=0 test4 (ColaPriorizacionTest) \n");
  */  
    printf("%%SUITE_FINISHED%% time=0\n");

    return (EXIT_SUCCESS);
}

void imprimirTrabajos (tLista pTrabajos){
    
    if (pTrabajos)
    {
        tIteradorLista iterador = listaObtenerIterador(pTrabajos);
        while (listaIteradorMoverSiguiente(iterador))
        {
            tTrabajo trabajo = listaIteradorActual(iterador);
            imprimirTrabajo (trabajo);
        }
        listaLiberarIterador(iterador);
    }
}

void imprimirTrabajo (tTrabajo pTrabajo) {
    if (pTrabajo)
    {
        printf("\n[Path: %s][Potencia Proceso: %d][Prioridad: %d][Memora Requerida: %d][Tiempo Ejecucion: %d]"
            ,trabajoGetPathEjecutable(pTrabajo)
            ,trabajoGetPotenciaProceso(pTrabajo)
            ,trabajoGetPrioridad(pTrabajo)            
            ,trabajoGetRequerimientoMemoria(pTrabajo)
            ,trabajoGetTiempoEjecucion(pTrabajo)
        );
    }
}

void imprimirColaPriorizacion (tColaPriorizacion pColaPriorizacion){

    if (pColaPriorizacion)
    {
        // Imprimo la lista de priorizacion.
       tColaPriorizacionIterador iteradorCola = colaPriorizacionIterador(pColaPriorizacion);
       while (colaPriorizacionIteradorMoverSiguiente(iteradorCola))
       {
           tTrabajo trabajo = colaPriorizacionIteradorActual(iteradorCola);
           imprimirTrabajo(trabajo);
       }
       colaPriorizacionIteradorLiberar(iteradorCola);       
    }
}

void test1() {
    printf("\nColaPriorizacionTest Crear e iterar cola de priorizacion vacia");
    
    tColaPriorizacion cola;
    colaPriorizacionCrear(&cola);
    
    if (cola)
    {
        tColaPriorizacionIterador iterador = colaPriorizacionIterador(cola);
        while (colaPriorizacionIteradorMoverSiguiente(iterador))
        {
            tTrabajo trabajo = colaPriorizacionIteradorActual(iterador);
            printf ("%s\n", trabajoGetPrioridad(trabajo));
        }
        colaPriorizacionIteradorLiberar(iterador);
        printf(" [OK].\n");
    }
    else
        printf("%%TEST_FAILED%% time=0 testname=test1 (ColaPriorizacionTest) message=No se creo la cola de priorizacion.\n");
}

void test2() {

    tColaPriorizacion cola;
    colaPriorizacionCrear(&cola);
    
    if (cola)
    {
        /*
         *  JOB 2 1 1048576 /bin/test2 13
         *  JOB 0 3 1048576 /bin/test0 12
         *  JOB 3 1 2621440 /bin/test3 10
         *  JOB 4 4 4194304 /bin/test4 20
         */
        tTrabajo trabajoA;
        trabajoCrear(&trabajoA, 2, 1, 1024, "/bin/test2", 1048576);
        colaPriorizacionPriorizar(cola, trabajoA);

        tTrabajo trabajoB;
        trabajoCrear(&trabajoB, 0, 3, 2048, "/bin/test0", 1048576);
        colaPriorizacionPriorizar(cola, trabajoB);

        tTrabajo trabajoC;
        trabajoCrear(&trabajoC, 3, 1, 4096, "/bin/test3", 2621440);
        colaPriorizacionPriorizar(cola, trabajoC);
        
        tTrabajo trabajoD;
        trabajoCrear(&trabajoD, 4, 4, 2048, "/bin/test4", 4194304);
        colaPriorizacionPriorizar(cola, trabajoD);        

        printf("\n");
        tColaPriorizacionIterador iterador = colaPriorizacionIterador(cola);
        while (colaPriorizacionIteradorMoverSiguiente(iterador))
        {
            tTrabajo trabajo = colaPriorizacionIteradorActual(iterador);
            imprimirTrabajo(trabajo);
        }
        colaPriorizacionIteradorLiberar(iterador);
        
        colaPriorizacionRemover(cola, trabajoA);        
        colaPriorizacionRemover(cola, trabajoB);        
        

        printf("\n");
        iterador = colaPriorizacionIterador(cola);
        while (colaPriorizacionIteradorMoverSiguiente(iterador))
        {
            tTrabajo trabajo = colaPriorizacionIteradorActual(iterador);
            imprimirTrabajo(trabajo);
        }
        colaPriorizacionIteradorLiberar(iterador);

        tTrabajo trabajoE;
        trabajoCrear(&trabajoE, 1, 2, 1048576, "/bin/test1", 11);
        colaPriorizacionPriorizar(cola, trabajoE);        

        printf("\n");
        iterador = colaPriorizacionIterador(cola);
        while (colaPriorizacionIteradorMoverSiguiente(iterador))
        {
            tTrabajo trabajo = colaPriorizacionIteradorActual(iterador);
            imprimirTrabajo(trabajo);
        }
        colaPriorizacionIteradorLiberar(iterador);

        
        trabajoDestruir(trabajoA);
        trabajoDestruir(trabajoB);
        trabajoDestruir(trabajoC);
        trabajoDestruir(trabajoD);
        trabajoDestruir(trabajoE);
        
        printf("\nColaPriorizacionTest Crear e iterar cola de priorizacion [OK]\n");    
    }
    else
        printf("%%TEST_FAILED%% time=0 testname=test2 (ColaPriorizacionTest) message=no se puede instanciar la cola de priorizacion.\n");
}

void test3() {
    
    tColaPriorizacion cola;
    colaPriorizacionCrear(&cola);

    if (cola)
    {
        tLista trabajos;
        listaCrear(&trabajos, &trabajoDestruir);
        if (trabajos)
        {
            // Populo la lista de trabajos.
            tTrabajo trabajo;
            trabajoCrear(&trabajo, 5, 1, 1024, "/test3 A", 10000);
            listaAgregarFinal(trabajos, trabajo);

            trabajo = NULL;
            trabajoCrear(&trabajo, 3, 2, 2048, "/test3 B", 15000);
            listaAgregarFinal(trabajos, trabajo);

            trabajo = NULL;
            trabajoCrear(&trabajo, 1, 1, 4096, "/test3 C", 60000);
            listaAgregarFinal(trabajos, trabajo);

            trabajo = NULL;
            trabajoCrear(&trabajo, 5, 2, 2048, "/test3 D", 20000);
            listaAgregarFinal(trabajos, trabajo);
            
            // Imprimo los trabajos
            imprimirTrabajos(trabajos);
            
            // Populo la cola de priorizacion con la lista de trabajos.
            tIteradorLista iteradorTrabajos = listaObtenerIterador(trabajos);
            while (listaIteradorMoverSiguiente(iteradorTrabajos))
            {
                trabajo = listaIteradorActual(iteradorTrabajos);
                colaPriorizacionPriorizar(cola, trabajo);
            }
            listaLiberarIterador(iteradorTrabajos);

            imprimirColaPriorizacion(cola);

            // Libero los recursos de la cola de priorizacion.
            colaPriorizacionDestruir(cola);
            
            // Elimino los trabajos.
            listaDestruir(trabajos);

            printf("\nColaPriorizacionTest Crear e iterar cola de priorizacion (con lista de trabajos) [OK]\n");    
        }
        else
            printf("%%TEST_FAILED%% time=0 testname=test2 (ColaPriorizacionTest) message=no se puede instanciar la lista de trabajos.\n");
    
    }
    else
        printf("%%TEST_FAILED%% time=0 testname=test3 (ColaPriorizacionTest) message=No se puede instanciar la cola de prioriacion.\n");        

}

void test4() {
    
    tColaPriorizacion cola;
    colaPriorizacionCrear(&cola);

    if (cola)
    {
        tLista trabajos;
        listaCrear(&trabajos, &trabajoDestruir);
        if (trabajos)
        {
            // Populo la lista de trabajos.
            tTrabajo trabajo;
            trabajoCrear(&trabajo, 5, 1, 1024, "/test4 A", 10000);
            listaAgregarFinal(trabajos, trabajo);

            trabajo = NULL;
            trabajoCrear(&trabajo, 3, 2, 2048, "/test4 B", 15000);
            listaAgregarFinal(trabajos, trabajo);

            trabajo = NULL;
            trabajoCrear(&trabajo, 1, 1, 4096, "/test4 C", 60000);
            listaAgregarFinal(trabajos, trabajo);

            trabajo = NULL;
            trabajoCrear(&trabajo, 5, 2, 2048, "/test4 D", 20000);
            listaAgregarFinal(trabajos, trabajo);
            
            // Imprimo los trabajos
            imprimirTrabajos(trabajos);
            
            // Populo la cola de priorizacion con la lista de trabajos.
            tIteradorLista iteradorTrabajos = listaObtenerIterador(trabajos);
            while (listaIteradorMoverSiguiente(iteradorTrabajos))
            {
                trabajo = listaIteradorActual(iteradorTrabajos);
                colaPriorizacionPriorizar(cola, trabajo);
            }
            listaLiberarIterador(iteradorTrabajos);

            printf ("\n Cola Priorizacion antes de eliminar el trabajo...\n");
            imprimirColaPriorizacion(cola);
            
            colaPriorizacionRemover(cola, trabajo);
            
            printf ("\n Cola Priorizacion luego de eliminar el trabajo...\n");
            imprimirColaPriorizacion(cola);

            // Libero los recursos de la cola de priorizacion.
            colaPriorizacionDestruir(cola);
            
            // Elimino los trabajos.
            listaDestruir(trabajos);

            printf("\nColaPriorizacionTest Remover un trabajo de la cola de priorizacion [OK]\n");    
        }
        else
            printf("%%TEST_FAILED%% time=0 testname=test4 (ColaPriorizacionTest) message=no se puede instanciar la lista de trabajos.\n");
    
    }
    else
        printf("%%TEST_FAILED%% time=0 testname=test4 (ColaPriorizacionTest) message=No se puede instanciar la cola de prioriacion.\n");        

}